package com.micro.ai.commons.util;

import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * 安全工具类
 * 
 * @author micro-ai
 * @since 0.0.1
 */
@Slf4j
public final class SecurityUtils {

    private SecurityUtils() {
        throw new UnsupportedOperationException("工具类不允许实例化");
    }

    /**
     * MD5加密
     */
    public static String md5(String input) {
        if (input == null || input.isEmpty()) {
            return null;
        }
        
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hash);
        } catch (NoSuchAlgorithmException e) {
            log.error("MD5加密失败", e);
            throw new RuntimeException("MD5加密失败", e);
        }
    }

    /**
     * SHA-256加密
     */
    public static String sha256(String input) {
        if (input == null || input.isEmpty()) {
            return null;
        }
        
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hash);
        } catch (NoSuchAlgorithmException e) {
            log.error("SHA-256加密失败", e);
            throw new RuntimeException("SHA-256加密失败", e);
        }
    }

    /**
     * SHA-512加密
     */
    public static String sha512(String input) {
        if (input == null || input.isEmpty()) {
            return null;
        }
        
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-512");
            byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hash);
        } catch (NoSuchAlgorithmException e) {
            log.error("SHA-512加密失败", e);
            throw new RuntimeException("SHA-512加密失败", e);
        }
    }

    /**
     * Base64编码
     */
    public static String base64Encode(String input) {
        if (input == null) {
            return null;
        }
        return Base64.getEncoder().encodeToString(input.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * Base64解码
     */
    public static String base64Decode(String input) {
        if (input == null || input.isEmpty()) {
            return null;
        }
        try {
            byte[] decoded = Base64.getDecoder().decode(input);
            return new String(decoded, StandardCharsets.UTF_8);
        } catch (IllegalArgumentException e) {
            log.error("Base64解码失败", e);
            return null;
        }
    }

    /**
     * 生成随机盐值
     */
    public static String generateSalt(int length) {
        if (length <= 0) {
            throw new IllegalArgumentException("盐值长度必须大于0");
        }
        
        SecureRandom random = new SecureRandom();
        byte[] salt = new byte[length];
        random.nextBytes(salt);
        return Base64.getEncoder().encodeToString(salt);
    }

    /**
     * 生成随机令牌
     */
    public static String generateToken(int length) {
        if (length <= 0) {
            throw new IllegalArgumentException("令牌长度必须大于0");
        }
        
        SecureRandom random = new SecureRandom();
        byte[] token = new byte[length];
        random.nextBytes(token);
        return Base64.getUrlEncoder().withoutPadding().encodeToString(token);
    }

    /**
     * 密码加密（加盐）
     */
    public static String encryptPassword(String password, String salt) {
        if (password == null || password.isEmpty()) {
            return null;
        }
        if (salt == null || salt.isEmpty()) {
            salt = generateSalt(16);
        }
        return sha256(password + salt);
    }

    /**
     * 验证密码
     */
    public static boolean verifyPassword(String password, String salt, String encryptedPassword) {
        if (password == null || salt == null || encryptedPassword == null) {
            return false;
        }
        String encrypted = encryptPassword(password, salt);
        return encryptedPassword.equals(encrypted);
    }

    /**
     * 生成访问令牌
     */
    public static String generateAccessToken() {
        return generateToken(32);
    }

    /**
     * 生成刷新令牌
     */
    public static String generateRefreshToken() {
        return generateToken(64);
    }

    /**
     * 字节数组转十六进制字符串
     */
    private static String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }
}
